package com.sunlake.spring.main.config;

import com.sunlake.spring.main.common.enums.role.RoleEnum;
import com.sunlake.spring.main.model.auth.po.UsersPO;
import com.sunlake.spring.main.common.utils.JwtTokenUtil;
import io.jsonwebtoken.MalformedJwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

/**
 * JWT认证过滤器
 * 验证请求中的JWT令牌
 * @author by liuhanzhi
 */
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private JwtConfig jwtConfig;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        // 获取请求头中的令牌
        String tokenHeader = request.getHeader(jwtConfig.getHeader());
        // 如果请求头中包含令牌前缀
        if (tokenHeader != null && tokenHeader.startsWith(jwtConfig.getTokenPrefix())) {
            // 提取令牌并去除所有空格
            String token = tokenHeader.replace(jwtConfig.getTokenPrefix(), "").replaceAll("\\s+", "");

            if (token.isEmpty()) {
                logger.warn("令牌为空，无法进行认证");
                SecurityContextHolder.clearContext();
            } else {
                try {
                    // 从令牌中获取用户信息
                    Long userId = jwtTokenUtil.getUserIdFromToken(token);
                    String username = jwtTokenUtil.getUsernameFromToken(token);

                    // 验证令牌
                    if (userId != null && username != null && jwtTokenUtil.validateToken(token, username, userId)) {
                        // 从token中获取用户角色
                        String roleCode = jwtTokenUtil.getUserRoleFromToken(token);
                        RoleEnum role = RoleEnum.USER;
                        if (roleCode != null) {
                            role = RoleEnum.fromCode(roleCode);
                        }

                        // 创建用户对象并设置角色
                        UsersPO userDetails = new UsersPO();
                        userDetails.setId(userId.intValue());
                        userDetails.setUsername(username);
                        userDetails.setRole(role);

                        // 创建并设置Authentication对象
                        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                                userDetails, null, userDetails.getAuthorities());
                        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                        SecurityContextHolder.getContext().setAuthentication(authentication);
                    }
                } catch (MalformedJwtException e) {
                    logger.error("JWT令牌格式错误（可能包含空格）: {}", e);
                    SecurityContextHolder.clearContext();
                } catch (Exception e) {
                    logger.error("JWT令牌验证失败: {}", e);
                    SecurityContextHolder.clearContext();
                }
            }
        }

        // 继续过滤链
        filterChain.doFilter(request, response);
    }
}